package com.xiang.api.common;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.xiang.api.Util;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

@MappedJdbcTypes(JdbcType.VARBINARY)
@MappedTypes({ List.class })
public abstract class ListTypeHandler<T> extends BaseTypeHandler<List<T>> {

  @Override
  public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType)
      throws SQLException {
    String content = parameter == null ? null : Util.toJString(parameter);
    ps.setString(i, content);
  }

  @Override
  public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
    return this.getListByJsonArrayString(rs.getString(columnName));
  }

  @Override
  public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    return this.getListByJsonArrayString(rs.getString(columnIndex));
  }

  @Override
  public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    return this.getListByJsonArrayString(cs.getString(columnIndex));
  }

  private List<T> getListByJsonArrayString(String content) {
    try {
      return JSON.parseObject(content, this.specificType());
    } catch (Exception e) {
    }
    return new ArrayList<>();
  }

  /**
   * 具体类型，由子类提供
   *
   * @return 具体类型
   */
  protected abstract TypeReference<List<T>> specificType();

}
